package com.bzy.common.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

public class DateUtils {

	public static String ISO_DATETIME_FORMATTER = "yyyy-MM-dd HH:mm:ss";

	public static String ISO_DATETIME_FORMATTER_ = "yyyy-MM-dd HH:mm";

	public static String ISO_DATE_FORMATTER = "yyyy-MM-dd";

	public static String ISO_DATE_FORMATTER_2 = "yyyy-M-d";

	public static String ISO_DATE_FORMATTER_MMDD = "MM-dd";

	public static String ISO_DATE_FORMATTER_YYYYMM = "yyyy-MM";

	public static String ISO_TIME_FORMATTER = "HH:mm:ss";

	public static String toDateString(Date date) {
		return toDateString(date, ISO_DATE_FORMATTER);
	}

	public static String toTimeString(Date date) {
		return toDateString(date, ISO_TIME_FORMATTER);
	}

	public static String toDateTimeString(Date date) {
		return toDateString(date, ISO_DATETIME_FORMATTER);
	}

	public static Date TimeStamp2Date(String timestampString) {
		Date result = null;
		if (timestampString != null) {
			Long timestamp = Long.parseLong(timestampString) * 1000;
			result = new Date(timestamp);
		}
		return result;
	}

	public static Date getDiffDate(Date date, int dateDiff) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(calendar.DATE, dateDiff);
		return calendar.getTime();
	}

	public static boolean isFutureDate(Date date) {
		return date.after(new Date());
	}

	public static boolean isPreviouDate(Date date) {
		return date.before(DateUtils.getDiffDate(new Date(), -1));
	}

	public static long calcDaysBetween(Date date1, Date date2) {
		long days = (date1.getTime() - date2.getTime()) / (24 * 60 * 60 * 1000);
		return days;
	}

	public static Date calcDateByDiff(Date date, long diffDays) {
		return new Date(date.getTime() + diffDays * (24 * 60 * 60 * 1000));
	}

	public static String getDateFromString(String string) {
		String dateString = null;
		String regex = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(string);
		while (matcher.find()) {
			dateString = matcher.group();
			break;
		}
		return dateString;
	}

	public static String calculateDate(Integer type) {
		String finalDate = "";
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat(ISO_DATE_FORMATTER);
		if (type == 1) {
			// 当前时间
			finalDate = sdf.format(date);
		} else if (type == 2) {
			// 三天内
			finalDate = sdf.format(date.getTime() - 3 * 24 * 60 * 60 * 1000);
		} else if (type == 3) {
			// 七天内
			finalDate = sdf.format(date.getTime() - 7 * 24 * 60 * 60 * 1000);
		}
		return finalDate;
	}

	public static String toDateString(Date date, String formatter) {

		if (date == null || StringUtils.isBlank(formatter)) {
			return "";
		}

		SimpleDateFormat format = new SimpleDateFormat(formatter);
		return format.format(date);
	}

	public static Date toDate(String dateString) {
		return toDate(dateString, ISO_DATE_FORMATTER, ISO_DATETIME_FORMATTER, ISO_DATE_FORMATTER_2);
	}

	public static Date toDate(String dateString, String... parsePatterns) {

		if (dateString == null || StringUtils.isBlank(dateString)) {
			return null;
		}

		try {
			return org.apache.commons.lang3.time.DateUtils.parseDate(dateString, parsePatterns);
		} catch (ParseException e) {
			e.printStackTrace();
		}

		return null;

	}

	/**
	 * 根据用户生日计算年龄
	 */
	public static int getAgeByBirthday(Date birthday) {

		Calendar cal = Calendar.getInstance();

		// if (cal.before(birthday)) {
		// throw new IllegalArgumentException(
		// "The birthDay is before Now.It's unbelievable!");
		// }

		int yearNow = cal.get(Calendar.YEAR);
		int monthNow = cal.get(Calendar.MONTH) + 1;
		int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
		cal.setTime(birthday);
		int yearBirth = cal.get(Calendar.YEAR);
		int monthBirth = cal.get(Calendar.MONTH) + 1;
		int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

		int age = yearNow - yearBirth;
		if (monthNow <= monthBirth) {
			if (monthNow == monthBirth) {
				if (dayOfMonthNow < dayOfMonthBirth) {
					age--;
				}
			} else {
				age--;
			}
		}
		return age;
	}

	/**
	 * 判断一个月有多少天
	 * 
	 * @param year
	 * @param month
	 * @return
	 */
	public static int judgeDay(int year, int month) {
		Calendar c = Calendar.getInstance();
		c.set(Calendar.DAY_OF_MONTH, 1); // 设置日期
		c.set(Calendar.YEAR, year);
		c.set(Calendar.MONTH, month - 1);
		return c.getActualMaximum(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 获取当前时间的 前 和 后的天数
	 * 
	 * @param beforeDays
	 * @param currentDate
	 * @param afterDays
	 * @return
	 */
	public static List<Long> judeDateTimesList(int beforeDays, Date currentDate, int afterDays) {
		List<Long> dateList = new ArrayList<>();
		if (beforeDays != 0) {
			for (int i = 1; i <= beforeDays; i++) {
				long dayTimes = Math.abs((long) ((1000L * 1 * 60 * 60 * 24) * i));
				long howLong = currentDate.getTime() - dayTimes;
				dateList.add(howLong);
			}
			Collections.sort(dateList);
		}
		dateList.add(currentDate.getTime());
		if (afterDays != 0) {
			for (int j = 1; j <= afterDays; j++) {
				long dayTimes = Math.abs((long) ((1000L * 1 * 60 * 60 * 24) * j));
				long howLong = currentDate.getTime() + dayTimes;
				dateList.add(howLong);
			}
		}
		return dateList;
	}

	/**
	 * 通过起始日期返回所有间隔日期
	 * 
	 * @param beginTime
	 *            开始时间 (yyyy-MM-dd)
	 * @param endTime
	 *            结束时间 (yyyy-MM-dd)
	 */
	public static List<String> queryDateByBE(String beginTime, String endTime) {
		DateFormat FORMATTER = new SimpleDateFormat("yyyy-MM-dd");
		List<String> list = new ArrayList<String>();
		try {
			Calendar startDay = Calendar.getInstance();
			Calendar endDay = Calendar.getInstance();
			Date beginDate = FORMATTER.parse(beginTime);
			Date endDate = FORMATTER.parse(endTime);
			beginTime = toDateString(beginDate);
			endTime = toDateString(endDate);
			startDay.setTime(beginDate);
			endDay.setTime(endDate);
			list = new ArrayList<String>();
			String s1 = "";
			s1 = beginTime;
			list.add(s1);
			if (!beginTime.equals(endTime)) {
				if (startDay.compareTo(endDay) <= 0) {
					Calendar currentPrintDay = startDay;
					while (true) {
						String s = "";
						currentPrintDay.add(Calendar.DATE, 1);
						if (currentPrintDay.compareTo(endDay) == 0) {
							break;
						}
						s = FORMATTER.format(currentPrintDay.getTime());
						list.add(s);
					}
					String s2 = "";
					s2 = endTime;
					list.add(s2);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}

	/**
	 * 正则
	 * @param ymd
	 * @return
	 */
	public static boolean isDate_ymd(String ymd){
		boolean is = false;
		String regexYear = "[0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3}"; //平年
		String regexYearRun = "([0-9]{2})(0[48]|[2468][048]|[13579][26])"; 		//闰年，能被4整除但不能被100整除
		String regexYearRun2 = "(0[48]|[2468][048]|[13579][26]00)";				//#闰年，能被400整除
		String regexYearMD = "(("+regexYearRun+")|("+regexYearRun2+"))-02-29";   //闰年匹配年月日
		String regexMonth31 = "(0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01])";		//#月日，1、3、5、7、8、10、12月有31天
		String regexMonth30 = "(0[469]|11)-(0[1-9]|[12][0-9]|30)";				//#月日，4、6、9、11月有30天
		String regexMonth28 = "02-(0[1-9]|[1][0-9]|2[0-8])";						//#平年2月只有28天，月日表示为【02-01至02-28】
		String regexYearMD2 = "("+regexYear+")-(("+regexMonth31+")|("+regexMonth30+")|("+regexMonth28+"))";
		String regex = "("+regexYearMD+")|("+regexYearMD2+")";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(ymd);
		is = matcher.matches();
		System.out.println("check return is : "+is);
		return is;
	}
	
	public static void main(String[] args) {
		// judeDateTimesList(2,new Date(),3);
//		String mmdd = toDateString(new Date());
//		System.out.println(mmdd);
		
//		List<String> result = queryDateByBE("2017-01-01 00:00:00", "2018-04-20 23:59:59");
//		List<String> result = queryDateByBE("", "");
//		System.out.println(JSONUtils.converterToString(result));
		if (!isDate_ymd("2018-05-UE")) {
			System.out.println("失败了");
		}
	}
}
